home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Desarrolladores / PlayerPRO 4.5.1 Dev.Kit / Plug-Ins / Import⁄Export Plugs / MTM.c < prev    next >
C/C++ Source or Header  |  1995-10-29  |  11KB  |  420 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 4.4x -- MTM to MADx & MADx to MTM
  4. //
  5. //    Version 1.0    - 14.3.95 ANR
  6. //
  7. //    To use with CodeWarrior 68K or PPC
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //    
  14. //    FAX:            (+41 22) 346 11 97
  15. //    Compuserve:        100277,164
  16. //    Internet:         rosset@dial.eunet.ch
  17. //
  18. /********************                        ***********************/
  19.  
  20. #include "MTM.h"
  21. #include "MAD.h"
  22. #include "RDriver.h"
  23.  
  24. #if defined(powerc) || defined(__powerc)
  25. enum {
  26.         PlayerPROPlug = kCStackBased
  27.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  28.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  29.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr*)))
  30.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADPartition*)))
  31.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  32. };
  33.  
  34. ProcInfoType __procinfo = PlayerPROPlug;
  35. #else
  36. #include <A4Stuff.h>
  37. #endif
  38.  
  39. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  40. {
  41.     if( PosX < 0) PosX = 0;
  42.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  43.         
  44.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  45. }
  46.  
  47. void pStrcpy(register unsigned char *s1, register unsigned char *s2)
  48. {
  49.     register short len, i;
  50.     
  51.     len = *s2;
  52.     for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
  53. }
  54.  
  55. unsigned long Tdecode32( void *msg_buf)
  56. {
  57.   unsigned char *buf = msg_buf;
  58.   
  59.   return( (unsigned long) buf[3] << 24) | ( (unsigned long) buf[2] << 16) | ( (unsigned long) buf[ 1] << 8) | ( (unsigned long) buf[0]);
  60. }
  61.  
  62. short Tdecode16( void *msg_buf)
  63. {
  64.   unsigned char *buf = msg_buf;
  65.   
  66.   return ( (short) buf[1] << 8) | ( (short) buf[0]);
  67. }
  68.  
  69.  
  70. struct MTMTrack* GetMTMCommand( short position, short whichTracks, Ptr PatPtr)
  71. {
  72.     Ptr                    aPtr;
  73.  
  74.     aPtr =     (    PatPtr +
  75.                 whichTracks * 192L +
  76.                 position * 3L);
  77.  
  78.     return (struct MTMTrack*) aPtr;
  79. }
  80.  
  81. OSErr ConvertMTM2Mad( MTMDef *MTMFile, long MTMSize, MADPartition *theMAD)
  82. {
  83.     short             i, x, z;
  84.     long             sndSize, OffSetToSample, MPatSize, temp, inOutCount;
  85.     Ptr                MaxPtr;
  86.     OSErr            theErr;
  87.     Ptr                theInstrument[ 64], destPtr;
  88.     long             finetune[16] = 
  89.     {
  90.         8363,    8413,    8463,    8529,    8581,    8651,    8723,    8757,
  91.         7895,    7941,    7985,    8046,    8107,    8169,    8232,    8280
  92.     };
  93.     
  94.     /**** Variables pour le MAD ****/
  95.     Cmd                *aCmd;
  96.  
  97.     /**** Variables pour le MTM ****/
  98.     
  99.     struct Instru        *instru[ 64];
  100.     struct MTMTrack        *theCom;
  101.     Ptr                    samplePtr, patPtr, positionPtr;
  102.     short                *patTracks; 
  103.     /********************************/
  104.  
  105.     /**** Calcul de divers offsets *****/
  106.  
  107.     MTMFile->tracks = Tdecode16( &MTMFile->tracks);
  108.     MTMFile->comments = Tdecode16( &MTMFile->comments);
  109.     
  110.     MaxPtr         = (Ptr) ( (long)    MTMFile + MTMFile);
  111.     positionPtr    = (Ptr) ( (long)    MTMFile + 66L + MTMFile->NOS*37L);
  112.     patPtr         = (Ptr) ( (long)    MTMFile + 194L + MTMFile->NOS*37L);
  113.     destPtr        = (Ptr) ( (long)    MTMFile + 194L + MTMFile->NOS*37L + MTMFile->tracks*192L);
  114.     patTracks    = (short*) destPtr;
  115.     samplePtr     = (Ptr) ( (long)    MTMFile + 194L + MTMFile->NOS*37L + MTMFile->tracks*192L +
  116.                                     (MTMFile->patNo + 1L)*32L*2L + MTMFile->comments);
  117.     
  118.     /**** Analyse des instruments ****/
  119.     if( MTMFile->NOS > 64) return MADUnknowErr;
  120.     
  121.     for( i = 0, OffSetToSample = 0L; i < MTMFile->NOS ; i++)
  122.     {
  123.         theInstrument[ i] = samplePtr + OffSetToSample;
  124.  
  125.         instru[ i] = (struct Instru*) ((long) MTMFile + 66L + i*37L);
  126.  
  127.         instru[ i]->size = Tdecode32( &instru[ i]->size);
  128.         instru[ i]->loopBegin = Tdecode32( &instru[ i]->loopBegin);
  129.         instru[ i]->loopEnd = Tdecode32( &instru[ i]->loopEnd);
  130.  
  131.  
  132.         sndSize = instru[ i]->size;
  133.         if( theInstrument[i] + sndSize > MaxPtr)
  134.         {
  135.             // sndSize = instru[ i]->size = MaxPtr - theInstrument[i];
  136.             return MADUnknowErr;
  137.         }
  138.         OffSetToSample += sndSize;
  139.     }
  140.  
  141.  
  142.     /***********************************************/
  143.     /******** Le MTM a été lu et analysé ***********/
  144.     /***** Copie des informations dans le MAD ******/
  145.     /***********************************************/
  146.     
  147.     
  148.     
  149.     /**************************/
  150.     /*** MAD Initialisation ***/
  151.     /**************************/
  152.     
  153.     inOutCount = sizeof( MADSpec);
  154.     theMAD->header = (MADSpec*) NewPtrClear( inOutCount);    
  155.     if( theMAD->header == 0L) return MADNeedMemory;
  156.     theMAD->header->MAD = 'MADH';
  157.     
  158.     /*****************************************/
  159.     /*** Copie des informations MTM -> MAD ***/
  160.     /*****************************************/
  161.     
  162.     for(i=0; i<22; i++)
  163.     {
  164.         theMAD->header->name[i] = MTMFile->songname[i];
  165.     }
  166.     
  167.     theMAD->header->tempo = 125;
  168.     theMAD->header->speed = 6;
  169.     theMAD->header->numPat                 = MTMFile->patNo + 1;
  170.     theMAD->header->numPointers            = MTMFile->positionNo;
  171.     for(i=0; i<128; i++)
  172.     {
  173.         theMAD->header->oPointers[ i]     = positionPtr[ i];
  174.     }
  175.     theMAD->header->numChn                 = MTMFile->trackback;
  176.  
  177.     for(i = 0; i < MTMFile->NOS; i++)
  178.     {
  179.         for( x = 0; x < 22; x++) theMAD->header->fid[i].name[x] = instru[i]->name[x];
  180.         theMAD->header->fid[i].type = 0;
  181.         
  182.         if( instru[ i]->size > 0)
  183.         {
  184.             sData    *curData;
  185.             
  186.             theMAD->header->fid[i].numSamples = 1;
  187.             
  188.             curData = theMAD->sample[ i][ 0] = (sData*) NewPtrClear( sizeof( sData));
  189.             
  190.             curData->size        = instru[ i]->size;
  191.             curData->loopBeg     = instru[ i]->loopBegin;
  192.             curData->loopSize     = instru[ i]->loopEnd - instru[i]->loopBegin;
  193.             curData->vol        = instru[ i]->volume;
  194.             curData->c2spd        = finetune[ instru[ i]->fineTune];
  195.             curData->loopType    = 0;
  196.             curData->amp        = 8;
  197.             curData->panning    = 0;
  198.             curData->relNote    = 0;
  199.         //    for( x = 0; x < 22; x++) curData->name[x] = instru[i]->name[x];
  200.             
  201.             curData->data         = NewPtr( curData->size);
  202.             if( curData->data == 0L) DebugStr("\pInstruments: I NEED MEMORY !!! NOW !");
  203.             
  204.             BlockMove( theInstrument[i], curData->data, curData->size);
  205.             
  206.             destPtr = curData->data;
  207.             for( temp = 0; temp < curData->size; temp++) *(destPtr + temp) -= 0x80;
  208.         }
  209.         else theMAD->header->fid[ i].numSamples = 0;
  210.     }
  211.     
  212.     for(i=0; i<theMAD->header->numPat; i++)
  213.     {
  214.         
  215.         theMAD->partition[ i] = (PatData*) NewPtrClear( sizeof( PatData) + theMAD->header->numChn * 64L * sizeof( Cmd));
  216.         if( theMAD->partition[ i] == 0L) return MADNeedMemory;
  217.  
  218.         theMAD->partition[ i]->header.size = 64L;
  219.         theMAD->partition[ i]->header.compMode = 'NONE';
  220.  
  221.         for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0;
  222.  
  223.         theMAD->partition[ i]->header.patBytes = 0L;
  224.         theMAD->partition[ i]->header.unused2 = 0L;
  225.  
  226.         MaxPtr = (Ptr) theMAD->partition[ i];
  227.         MaxPtr += sizeof( PatData) + theMAD->header->numChn * 64L * sizeof( Cmd);
  228.  
  229.         for( z = 0; z < 32; z++) patTracks[ z] = Tdecode16( &patTracks[ z]);
  230.  
  231.         for(x=0; x<64; x++)
  232.         {
  233.             for(z=0; z<theMAD->header->numChn; z++)
  234.             {
  235.                 aCmd = GetMADCommand(  x,  z, theMAD->partition[ i]);
  236.                 if( (Ptr) aCmd + sizeof( Cmd) > MaxPtr) return MADUnknowErr;
  237.                 
  238.                 if( patTracks[ z] == 0)
  239.                 {
  240.                     aCmd->ins        = 0;
  241.                     aCmd->note        = 0xFF;
  242.                     aCmd->cmd        = 0;
  243.                     aCmd->arg        = 0;
  244.                     aCmd->vol        = 0xFF;
  245.                 }
  246.                 else
  247.                 {
  248.                     theCom         = GetMTMCommand(    x,
  249.                                                     patTracks[ z],
  250.                                                     (Ptr) patPtr);
  251.                     
  252.                     aCmd->ins     = theCom->instru;
  253.                     
  254.                     if( theCom->pitch)
  255.                     {
  256.                         aCmd->note     = theCom->pitch + 22;
  257.                     }
  258.                     else aCmd->note = 0xFF;
  259.                     
  260.                     aCmd->cmd     = theCom->EffectCmd;
  261.                     aCmd->arg     = theCom->EffectArg;
  262.                     aCmd->vol    = 0xFF;
  263.                 }
  264.             }
  265.         }
  266.         
  267.         /*** Avance dans les tracks-patterns suivants ***/
  268.         patTracks += 32;
  269.     }
  270.     
  271.     return noErr;
  272. }
  273.  
  274. OSErr ExtractInfo( PPInfoRec *info, MTMDef *myFile)
  275. {
  276.     long    PatternSize;
  277.     short    i;
  278.     short    maxInstru;
  279.     short    tracksNo;
  280.     
  281.     for( i = 0; i < sizeof( myFile->songname); i++)
  282.     {
  283.         info->internalFileName[ i] = myFile->songname[ i];
  284.     }
  285.     info->internalFileName[ 21] = 0;
  286.     CtoPstr( (Ptr) info->internalFileName);
  287.  
  288.     pStrcpy( info->formatDescription, "\pMTM Plug");
  289.  
  290.     info->totalPatterns        = myFile->patNo;
  291.     info->partitionLength    = myFile->positionNo;
  292.     info->totalTracks        = myFile->tracks;
  293.     info->totalInstruments    = myFile->NOS;
  294.     info->signature            = 'MTM ';
  295.  
  296.     return noErr;
  297. }
  298.  
  299. OSErr TestFile( MTMDef *myFile)
  300. {    
  301.     if(    myFile->Id[ 0] == 'M' &&
  302.         myFile->Id[ 1] == 'T' &&
  303.         myFile->Id[ 2] == 'M') return noErr;
  304.         
  305.     else return MADFileNotSupportedByThisPlug;
  306. }
  307.  
  308. /*****************/
  309. /* MAIN FUNCTION */
  310. /*****************/
  311.  
  312. OSErr main( OSType order, FSSpec *AlienFileFSSpec, MADPartition *MadFile, PPInfoRec *info)
  313. {
  314.     OSErr    myErr;
  315.     Ptr        AlienFile;
  316.     short    vRefNum, iFileRefI;
  317.     long    dirID, sndSize;
  318.     
  319. #ifndef powerc
  320.     long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  321. #endif
  322.  
  323.     HGetVol( 0L, &vRefNum, &dirID);
  324.     HSetVol( 0L, AlienFileFSSpec->vRefNum, AlienFileFSSpec->parID);
  325.  
  326.     myErr = noErr;
  327.  
  328.     switch( order)
  329.     {
  330.         case 'IMPL':
  331.             myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
  332.             if( myErr == noErr)
  333.             {
  334.                 GetEOF( iFileRefI, &sndSize);
  335.             
  336.                 // ** TEST MEMOIRE :  Environ 2 fois la taille du fichier**
  337.                 AlienFile = NewPtr( sndSize * 2L);
  338.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  339.                 // ** 
  340.                 
  341.                 else
  342.                 {
  343.                     DisposPtr( AlienFile);
  344.                     
  345.                     AlienFile = NewPtr( sndSize);
  346.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  347.                     if( myErr == noErr)
  348.                     {
  349.                         myErr = TestFile( (MTMDef*) AlienFile);
  350.                         if( myErr == noErr)
  351.                         {
  352.                             myErr = ConvertMTM2Mad( (MTMDef*) AlienFile, GetPtrSize( AlienFile), MadFile);
  353.                         }
  354.                     }
  355.                     DisposPtr( AlienFile);    AlienFile = 0L;
  356.                 }
  357.                 FSClose( iFileRefI);
  358.             }
  359.         break;
  360.         
  361.         case 'TEST':
  362.             myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
  363.             if( myErr == noErr)
  364.             {
  365.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  366.                 
  367.                 AlienFile = NewPtr( sndSize);
  368.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  369.                 else
  370.                 {
  371.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  372.                     if( myErr == noErr)
  373.                     {
  374.                         myErr = TestFile( (MTMDef*) AlienFile);
  375.                     }
  376.                     DisposPtr( AlienFile);    AlienFile = 0L;
  377.                 }
  378.                 FSClose( iFileRefI);
  379.             }
  380.         break;
  381.         
  382.         case 'EXPL':
  383.             myErr = MADOrderNotImplemented;
  384.         break;
  385.  
  386.         case 'INFO':
  387.             myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
  388.             if( myErr == noErr)
  389.             {
  390.                 GetEOF( iFileRefI, &info->fileSize);
  391.             
  392.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  393.                 
  394.                 AlienFile = NewPtr( sndSize);
  395.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  396.                 else
  397.                 {
  398.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  399.                     if( myErr == noErr)
  400.                     {
  401.                         myErr = ExtractInfo( info, (MTMDef*) AlienFile);
  402.                     }
  403.                     DisposPtr( AlienFile);    AlienFile = 0L;
  404.                 }
  405.                 FSClose( iFileRefI);
  406.             }
  407.         break;
  408.         
  409.         default:
  410.             myErr = MADOrderNotImplemented;
  411.         break;
  412.     }
  413.  
  414.     HSetVol( 0L, vRefNum, dirID);
  415.  
  416.     #ifndef powerc
  417.         SetA4( oldA4);
  418.     #endif
  419.     return myErr;
  420. }